package com.android.gui;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import com.android.controller.Controller;
import com.android.gui.CanvasDrawingActivity.DrawingPanel;
import com.android.networking.connection.Connection;
import com.android.networking.message.DataMessage;
import com.android.networking.message.DataPacket;


public class GuesserSideActivity extends  Activity   {
	private ArrayList<Path> _graphics = new ArrayList<Path>();
	private Paint mPaint;
	private  String clientMessage;
	static ServerSocket providerSocket;
	//Socket connection = null;
	PrintWriter out;
	BufferedReader in;
	String message;
	private static TextView serverStatus;
	private static SurfaceView sv;
    static int col = 0xffffffff; 

    //
    LinearLayout linear, linear1;
    TextView text1,text2,text3,text4;
    EditText text5;
    TableLayout _table;
    TableRow r1, r2, r3,r4;
   
    Button b1, b2, b3;   
	Controller cont = new Controller();
	ArrayList<MotionEvent> p = new ArrayList<MotionEvent>();
	int pathcount = 0;
	
	/*public void setGraphics(Path path){
		_graphics.add(path);
	}*/
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GuesserSideActivity obj = new GuesserSideActivity();
        _table = new TableLayout(this);
        mPaint = new Paint();   
        r1 = new TableRow(this);
        text1 = new TextView(this);
        text1.setText("This is text1!");
        text2 = new TextView(this);
        text2.setText("This is text2!");
   
        r1.addView(text1);
        r1.addView(text2); 
        r2 = new TableRow(this);
        text3 = new TextView(this);
        text3.setText("This is text3!");
        text4 = new TextView(this);
        text4.setText("This text4!");
        r2.addView(text3);
        r2.addView(text4); 
       
        linear = new LinearLayout(this);
        linear.setOrientation(LinearLayout.VERTICAL);
        sv = new SurfaceView(this);
        sv = new DrawingPanel(this);
        DrawingPanel sv1 = new DrawingPanel(this);
       
       
        linear.addView(sv,480,600);
        linear.addView(sv1,480,600);
       
        r4 = new TableRow(this);
        r4.setOrientation(TableLayout.HORIZONTAL);
        b1 = new Button(this);
        b1.setText("Button1");
        b1.setMinimumWidth(235);
        b2 = new Button(this);
        b2.setText("Go");
        b2.setMaxWidth(25);
        b1.setText("Eraser");
        b2.setText("Go");
        text5 = new EditText(this);
        text5.setMinimumWidth(350);
        CharSequence ss=text5.getText();
                
        r4.addView(text5);
        r4.addView(b2);
     //   r4.addView(b1);
     //   r4.addView(b2);
        _table.addView(r4);
        _table.addView(r1);
        _table.addView(r2);
        _table.addView(linear);
        
       
       
       
        setContentView(_table);
        sv.setDrawingCacheEnabled(true);
        //sv1.setDrawingCacheEnabled(true);
        
   /*     GuesserSideActivity obj = new GuesserSideActivity();
       //obj.createConnection();
        DrawingPanel dp = (com.android.gui.GuesserSideActivity.DrawingPanel) sv;
       // if(cont.test()){
	        setContentView(dp);
	     */   Log.d("Draw","In onCreate");
	        mPaint = new Paint();
	        mPaint.setDither(true);   
	        mPaint.setColor(Color.WHITE);
	        mPaint.setStyle(Paint.Style.STROKE);
	        mPaint.setStrokeJoin(Paint.Join.ROUND);
	        mPaint.setStrokeCap(Paint.Cap.ROUND);
	        mPaint.setStrokeWidth(3);
	        b2.setOnClickListener(bListener);
	        //sv1.onDataReceived();
	        DataReceive data = new DataReceive(sv1.get_thread(), sv1.getPath());
	        Thread t = new Thread(data);
	        t.start();
        //}
		
       
	}
private OnClickListener bListener = new OnClickListener() {
	    
	    public void onClick(View v) {
	      // do something when the button is clicked
//	    	v.clearAnimation();
	    	
	    	InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            inputManager.hideSoftInputFromWindow(text5.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);	    	
            //text3.setText(text5.getText());
            //text5.setText("");
            String answer = text5.getText().toString();
            DataMessage message= new DataMessage(0,0,null,answer,new ArrayList(),null,0,0,null);
            message.sendAnswer();
            Connection conn = Connection.getInstanceOfConnection();
			Socket csocket;
			csocket = conn.getClientSocket();
			try {
				out = new PrintWriter(csocket.getOutputStream(), true);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.println(message.toString());
	    }
	};

	

	protected void onStop(){
		Log.d("Draw:","Bye Bye!!!");
		try{
		//	in.close();
		//	out.close();
		providerSocket.close();
		}catch(Exception ex){}
   		System.exit(0);
	}
	 
	class DrawingPanel extends SurfaceView implements SurfaceHolder.Callback {
		private DrawingThread _thread;
		private Path path;
				
		public DrawingPanel(Context context) {
			super(context);
            getHolder().addCallback(this);
            _thread = new DrawingThread(getHolder(), this);
            Log.d("Draw","In DrawingPanel Constructor");
		}
		
		
		public DrawingThread get_thread() {
			return _thread;
		}


		public void set_thread(DrawingThread _thread) {
			this._thread = _thread;
		}


		public Path getPath() {
			return path;
		}


		public void setPath(Path path) {
			this.path = path;
		}


		/*public boolean onDataReceived(){
			Connection conn = Connection.getInstanceOfConnection();
			Socket csocket;
			csocket = conn.getClientSocket();
			while(true)
			{
				
				if(csocket==null)
				{
					continue;
				}
				else
				{
					break;
				}
			}
			try {				
				 in = new BufferedReader(new InputStreamReader(
                         csocket.getInputStream()));
				 String cstr;
				// while((cstr = in.readLine())!=null){
								 			 
					 //String cstr = in.readLine();
					 //Log.d("App",cstr);
					// DataMessage dm = DataMessage.getDataMessageInstance(cstr);
					// DataPacket cdp = dm.getLocalPack(); 
				 	
					 DataPacket cdp = null;
						synchronized (_thread.getSurfaceHolder()) {
				            //	if(event.getAction() == MotionEvent.ACTION_DOWN){
							Log.d("App","In printing pixels");
							//sv.buildDrawingCache();
				            		path = new Path();
				            		int ci=0;
				            		ArrayList s = cdp.getPointPath();
				            		for (ci = 0; ci<s.size(); ci++)
				            		{
				            			MotionEvent event = (MotionEvent) cdp.getPointPath().get(ci);
				            			path.moveTo(event.getX(), event.getY());
				            			path.lineTo(event.getX(), event.getY());
				            			_graphics.add((Path)s.get(ci));
				            			
				            		}
							}
				 //}
				 return true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
				return true;
		}*/
		
		@Override
        public synchronized void onDraw(Canvas canvas) {
			try{
			for (Path path : _graphics) {
				//canvas.drawPoint(graphic.x, graphic.y, mPaint);
					canvas.drawPath(path, mPaint);
			}
			}catch(Exception ex){
			
			}
			
		}
		
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
								   int height) {
			// TODO Auto-generated method stub
			
		}
		
		public void surfaceCreated(SurfaceHolder holder) {
			// TODO Auto-generated method stub
			Log.d("Draw","In surfaceCreated");
			_thread.setRunning(true);
            _thread.start();
		}
		
		public void surfaceDestroyed(SurfaceHolder holder) {
			// TODO Auto-generated method stub
			Log.d("Draw","In surfaceDestroyed");
			boolean retry = true;
            _thread.setRunning(false);
            while (retry) {
                try {
                    _thread.join();
                    retry = false;
                } catch (InterruptedException e) {
                    // we will try it again and again...
                }
            }
		}
	}
    class DataReceive implements Runnable{
    	private DrawingThread _thread;
		private Path path;
				
		public DataReceive(DrawingThread thread1,Path path1) {

            _thread = thread1;
            path = path1;
            Log.d("Draw","In DataReceive Constructor");
		}

		public void run() {
			// TODO Auto-generated method stub

			Connection conn = Connection.getInstanceOfConnection();
			Socket csocket;
			csocket = conn.getClientSocket();
			while (true) {

				if (csocket == null) {
					continue;
				} else {
					break;
				}
			}
			try {
				
				in = new BufferedReader(new InputStreamReader(
						csocket.getInputStream()));
				String cstr;
				float oldX = 0, oldY = 0;
				path = new Path();
				while ((cstr = in.readLine()) != null) {

					// String cstr = in.readLine();
					Log.d("App", cstr);
					DataMessage dm = DataMessage.getDataMessageInstance(cstr);
					if(dm==null)
						continue;
					DataPacket cdp = dm.getLocalPack();
					if(cdp==null)
						continue;
					synchronized (_thread.getSurfaceHolder()) {
						// if(event.getAction() == MotionEvent.ACTION_DOWN){
						Log.d("App", "In printing pixels");
						// sv.buildDrawingCache();						
						int ci = 0;
						ArrayList s = cdp.getPointPath();
						if(s==null)
							continue;
						//for (ci = 0; ci < s.size();) {
							
							/* MotionEvent event = (MotionEvent)
							 * cdp.getPointPath().get(ci);
							 * path.moveTo(event.getX(), event.getY());
							 * path.lineTo(event.getX(), event.getY());*/
							 
							//_graphics.add((Path) s.get(ci));
							
							if(s.get(ci).toString().equals("ACTION_DOWN")){
			            		//path = new Path();
								_graphics = new ArrayList<Path>();
			            		path.moveTo(((Float)s.get(ci+1)).floatValue(),((Float)s.get(ci+2)).floatValue() );
			            		path.lineTo(((Float)s.get(ci+1)).floatValue(),((Float)s.get(ci+2)).floatValue());
			            		//oldX = ((Float)s.get(ci+1)).floatValue();
			            		//oldY = ((Float)s.get(ci+2)).floatValue();
			            		//ci+=2; 
			            		//p.add(event);
			            		            		
			            	}else if(s.get(ci).toString().equals("ACTION_MOVE")){
			            		path.lineTo(((Float)s.get(ci+1)).floatValue(),((Float)s.get(ci+2)).floatValue() );
			            		//ci+=2;
			            		//p.add(event);
			            		
			            	}else if(s.get(ci++).toString().equals("ACTION_UP")){
			            		path.lineTo(((Float)s.get(ci)).floatValue(),((Float)s.get(ci+1)).floatValue() );
			            		//ci+=2;
			            		//p.add(event);
			            		//event.setAction(MotionEvent.ACTION_CANCEL);
			            		//cont.sendMessage(p);
			            		//_graphics.add(path);
			            	}
			            	//Log.d("App",event.getX()+"  "+event.getY());
			            	//p.add(event);
			            	//cont.sendMessage(p);
							synchronized(this){
			            	_graphics.add(path);
							}

						//}
					}
				}
			} catch (IOException e) {

				e.printStackTrace();
			}

		}
    	
		public void run1() {
			Log.d("App","In run method");
			ArrayList<String> pack = new ArrayList<String>();
			pack.add("messageType DataMessage requestType 0 sourceSeqNumber 0 pointsPathLen 1 pointPath  [ ACTION_DOWN,224.89635,217.83435; ]  answer  word  guessTime 0 hintCount 0 extraData ");
			pack.add("messageType DataMessage requestType 0 sourceSeqNumber 0 pointsPathLen 1 pointPath  [ ACTION_DOWN,225.89635,218.83435; ]  answer  word  guessTime 0 hintCount 0 extraData ");
			pack.add("messageType DataMessage requestType 0 sourceSeqNumber 0 pointsPathLen 1 pointPath  [ ACTION_DOWN,226.89635,219.83435; ]  answer  word  guessTime 0 hintCount 0 extraData ");
			pack.add("messageType DataMessage requestType 0 sourceSeqNumber 0 pointsPathLen 1 pointPath  [ ACTION_DOWN,227.89635,220.83435; ]  answer  word  guessTime 0 hintCount 0 extraData ");
			pack.add("messageType DataMessage requestType 0 sourceSeqNumber 0 pointsPathLen 1 pointPath  [ ACTION_DOWN,228.89635,221.83435; ]  answer  word  guessTime 0 hintCount 0 extraData ");
			pack.add("messageType DataMessage requestType 0 sourceSeqNumber 0 pointsPathLen 1 pointPath  [ ACTION_DOWN,229.89635,222.83435; ]  answer  word  guessTime 0 hintCount 0 extraData ");
			pack.add("messageType DataMessage requestType 0 sourceSeqNumber 0 pointsPathLen 1 pointPath  [ ACTION_DOWN,230.89635,223.83435; ]  answer  word  guessTime 0 hintCount 0 extraData ");
			pack.add("messageType DataMessage requestType 0 sourceSeqNumber 0 pointsPathLen 1 pointPath  [ ACTION_DOWN,231.89635,224.83435; ]  answer  word  guessTime 0 hintCount 0 extraData ");
			pack.add("messageType DataMessage requestType 0 sourceSeqNumber 0 pointsPathLen 1 pointPath  [ ACTION_DOWN,232.89635,225.83435; ]  answer  word  guessTime 0 hintCount 0 extraData ");
			try {
				
				String cstr;
				for (int i = 0; i < pack.size(); i++) {
					cstr = pack.get(i);
					// String cstr = in.readLine();
					Log.d("App", cstr);
					DataMessage dm = DataMessage.getDataMessageInstance(cstr);
					DataPacket cdp = dm.getLocalPack();

					synchronized (_thread.getSurfaceHolder()) 
					{
						// if(event.getAction() == MotionEvent.ACTION_DOWN){
						Log.d("Screen Write", "In printing pixels");
						// sv.buildDrawingCache();
						path = new Path();
						int ci = 0;
						ArrayList s = cdp.getPointPath();
						//for (ci = 0; ci < s.size(); ci++) {
							path.moveTo(((Float)s.get(ci+1)).floatValue(),((Float)s.get(ci+2)).floatValue() );
		            		path.lineTo(((Float)s.get(ci+1)).floatValue(),((Float)s.get(ci+2)).floatValue());				 
							//_graphics.add((Path) s.get(ci));
		            		_graphics.add(path);

						//}
						//Thread.sleep(1000);
					}
				}
			} catch (Exception e) {

				e.printStackTrace();
			}

		}
    }	
	class DrawingThread extends Thread {
        private SurfaceHolder _surfaceHolder;
        private DrawingPanel _panel;
        private boolean _run = false;
		
        public DrawingThread(SurfaceHolder surfaceHolder, DrawingPanel panel) {
        	Log.d("Draw","In DrawingThread Constructor");
            _surfaceHolder = surfaceHolder;
            _panel = panel;
        }
		
        public void setRunning(boolean run) {
            _run = run;
        }
		
        public SurfaceHolder getSurfaceHolder() {
            return _surfaceHolder;
        }
		
        @Override
        public void run() {
            Canvas c;
            while (_run) {
                c = null;
                try {
                    c = _surfaceHolder.lockCanvas(null);
                    synchronized (_surfaceHolder) {
                        _panel.onDraw(c);
                    }
                } finally {
                    // do this in a finally so that if an exception is thrown
                    // during the above, we don't leave the Surface in an
                    // inconsistent state
                    if (c != null) {
                        _surfaceHolder.unlockCanvasAndPost(c);
                    }
                }
            }
        }
    }
}
